.model tpascal
.386p
codeseg

	public  GausHorN
	public  GausVer1
	public  DiffHorN
	public  DiffHor1
	public  DiffVer1
	public  DiffHor2
	public  DiffVer2
	public  AbsHor
	public	AbsVect
	public	AbsCopy
	public	AddHor
	public	EdgeAsm
	public  EdgeLineAsm


AbsPrecission	equ 1

GausHorN proc uses ds esi,line:far ptr dword,sizex:word,times:word
	mov	cx,[times]
	jcxz    GausHNE
GausHN1:push    cx
	mov	cx,[sizex]
	dec	cx
	lds	si,[line]
	mov	ebx,[si+4]
	mov	edx,[si]
GausHN2:mov	eax,ebx
	add	eax,edx
	mov	ebx,edx
	add	eax,ebx
	mov	edx,[si+4]
	add	eax,edx
	shr	eax,2
	mov	[si],eax
	add	si,4
	loop	GausHN2
	mov	eax,ebx
	add	eax,eax
	add	eax,edx
	add	eax,edx
	shr	eax,2
	mov	[si],eax
	pop	cx
	loop	GausHN1
GausHNE:ret
endp

DiffHor1 proc uses ds esi es edi,L:far ptr dword,L1:far ptr dword,sizex:word
	mov	cx,[sizex]
	dec	cx
	lds	si,[L1]
	les	di,[L]
	mov	edx,[si+4]
DiffH12:mov	eax,[si+4]
	sub	eax,edx
	mov	edx,[si]
	add	si,4
	mov	es:[di],eax
	add	di,4
	loop	DiffH12
	mov	eax,0
	stosd
DiffH1E:ret
endp

DiffHorN proc uses ds esi,line:far ptr dword,sizex:word,times:word
	mov	cx,[times]
	jcxz    DiffHNE
DiffHN1:push    cx
	mov	cx,[sizex]
	dec	cx
	lds	si,[line]
	mov	eax,[si+4]
DiffHN2:neg	eax
	add	eax,[si+4]
	xchg	eax,[si]
	add	si,4
	loop	DiffHN2
	mov	dword ptr [si],0
	pop	cx
	loop	DiffHN1
DiffHNE:ret
endp

GausVer1 proc uses ds esi es edi,L:far ptr dword,L1:far ptr dword,L2:far ptr dword,L3:far ptr dword,sizex:word
	mov	cx,[sizex]
	les	di,[L]
	lfs	bx,[L1]
	lds	si,[L2]
	lgs	dx,[L3]
GausV11:mov	eax,[si]
	add	si,4
	add	eax,eax
	add	eax,fs:[bx]
	add	bx,4
	xchg	bx,dx
	add	eax,gs:[bx]
	xchg	bx,dx
	add	dx,4
	shr	eax,2
	mov	es:[di],eax
	add	di,4
	loop	GausV11
GausV1E:ret
endp

DiffVer1 proc uses ds esi es edi,L:far ptr dword,L1:far ptr dword,L2:far ptr dword,L3:far ptr dword,sizex:word
	mov	cx,[sizex]
	les	di,[L]
	lds	si,[L3]
	lfs	bx,[L1]
DiffV11:mov	eax,[si]
	add	si,4
	sub	eax,fs:[bx]
	add	bx,4
	mov	es:[di],eax
	add	di,4
	loop	DiffV11
DiffV1E:ret
endp

AbsVect	proc uses esi edi,A:dword,B:dword
	mov	eax,[A]
	mov	ebx,[B]
	test	eax,eax
	jz	AbsVec2
	jns     AbsVec1
	neg	eax
AbsVec1:xchg	eax,ebx
	test	eax,eax
	jnz	AbsVec3
AbsVec2:xchg	eax,ebx
	test	eax,eax
	jns     AbsVecE
	neg	eax
	jmp	AbsVecE
AbsVec3:jns     AbsVec4
	neg	eax
AbsVec4:cmp	eax,ebx
	ja	AbsVec5
	xchg	eax,ebx
AbsVec5:mov	esi,ebx
	shr	esi,2
	add	esi,eax
	mul	eax
	mov	ecx,edx
	xchg	eax,ebx
	mul	eax
	add	ebx,eax
	adc	ecx,edx
	xor	edi,edi
AbsVec6:mov	eax,ebx
	mov	edx,ecx
	div	esi
;	and	eax,not 1 ;!
	add	eax,esi
	rcr	eax,1
	cmp	eax,esi
	je	AbsVecE
	cmp	eax,edi
	mov	edi,esi
	mov	esi,eax
	jne	AbsVec6
AbsVecE:shld	edx,eax,10h
	ret
endp

if	AbsPrecission
AbsHor  proc  uses ds esi es edi,L:far ptr dword,L1:far ptr dword,sizex:word
	mov	cx,[sizex]
	lds	si,[L1]
	les	di,[L]
AbsH2:  push	cx
	push	dword ptr [si]
	push	dword ptr es:[di]
	call	AbsVect
	mov	es:[di],eax
	pop	cx
	add	si,4
	add	di,4
	loop	AbsH2
AbsHE:  ret
endp

else
AbsHor	proc uses ds esi es edi,L:far ptr dword,L1:far ptr dword,sizex:word
	mov	cx,[sizex]
	lds	si,[L1]
	les	di,[L]
	cld
AbsH2:  lodsd
	mov	edx,es:[di]
	test	eax,eax
	jns	AbsH3
	neg	eax
AbsH3:  xchg	eax,edx
	test	eax,eax
	jns	AbsH4
	neg	eax
AbsH4:  cmp	eax,edx
	jna     AbsH5
	xchg	eax,edx
AbsH5:	shr	eax,1
	add	eax,edx
	stosd
	loop	AbsH2
AbsHE:  ret
endp
endif

; ====== Canny v Assembleru ======

AbsCopy proc  uses ds esi es edi,L:far ptr dword,L1:far ptr dword,L2:far ptr dword,sizex:word
	mov	cx,[sizex]
	lds	si,[L1]
	lfs	bx,[L2]
	les	di,[L]
AbsC2:  push	cx
	push	bx
	push	dword ptr [si]
	push	dword ptr fs:[bx]
	call	AbsVect
	mov	es:[di],eax
	pop	bx
	pop	cx
	add	si,4
	add	di,4
	add	bx,4
	loop	AbsC2
AbsCE:  ret
endp

      ; Hrana ve smeru X, shodna znamenka
ET_XE	dw	4+4, 4,	0+4, 4
	dw     -4+4,-4,	0+4,-4
ET_XD	dw	4+4,-4,	0+4,-4
	dw     -4+4, 4,	0+4, 4
ET_YE	dw	4+4, 4,	4+4, 0
	dw     -4+4,-4,-4+4, 0
ET_YD	dw	4+4,-4,	4+4, 0
	dw     -4+4, 4,-4+4, 0


EdgeAsm	proc uses ds si di,L:far ptr dword,ux:dword,uy:dword,x:word
local	gl:dword,gh:dword,uz:dword
	mov	ax,[x]
	shl	ax,2
	mov	[x],ax
	mov	eax,[ux]
	mov	ebx,[uy]
	mov	ecx,eax
	or	ecx,ebx
	jz      EdgeA90
	test	eax,eax
	jns	EdgeA10
	neg	eax
EdgeA10:test	ebx,ebx
	jns	EdgeA15
	neg	ebx
EdgeA15:cmp	eax,ebx
	jge     EdgeA40
      ; Hrana ve smeru X
	lds	si,[L]
	lds	si,[si+4]
	add	si,[x]
	mov	eax,[si]	; G(0,0)
	mul	ebx		; abs(uy)
	mov	[gl],eax
	mov	[gh],edx
	mov     ecx,[ux]
	mov	eax,[ux]
	mov	ebx,[uy]

	test	eax,eax
	jz      EdgeA20
	test	ebx,ebx
	jz      EdgeA20

	xor	eax,ebx
	js      EdgeA20
      ; Shodna znamenka
	mov	eax,[ux]
	sub	eax,[uy]
	mov	[uz],eax
	mov	di,offset ET_XE
	jmp	Edge80
EdgeA20:
      ; Rozdilna znamenka
	mov	eax,[ux]
	add	eax,[uy]
	mov	[uz],eax
	mov	di,offset ET_XD
	jmp	Edge80
EdgeA40:
      ; Hrana ve smeru Y
	mov	ebx,eax		; abs(ux)
	lds	si,[L]
	lds	si,[si+4]
	add	si,[x]
	mov	eax,[si]	; G(0,0)
	mul	ebx		; abs(ux)
	mov	[gl],eax
	mov	[gh],edx
	mov     ecx,[uy]
	mov	eax,[ux]
	mov	ebx,[uy]

	test	eax,eax
	jz      EdgeA60
	test	ebx,ebx
	jz      EdgeA60

	xor	eax,ebx
	js      EdgeA60
      ; Shodna znamenka
	mov	eax,[uy]
	sub	eax,[ux]
	mov	[uz],eax
	mov	di,offset ET_YE
	jmp	Edge80
EdgeA60:
      ; Rozdilna znamenka
	mov	eax,[ux]
	add	eax,[uy]
	mov	[uz],eax
	mov	di,offset ET_YD

Edge80: push	ecx
	lds	si,[L]
	add	si,cs:[di]
	add	di,2
	lds	si,[si]
	add	si,cs:[di]
	add	di,2
	add	si,[x]
	mov	eax,[si]
	imul	ecx
	mov	ebx,eax
	mov	ecx,edx
	lds	si,[L]
	add	si,cs:[di]
	add	di,2
	lds	si,[si]
	add	si,cs:[di]
	add	di,2
	add	si,[x]
	mov	eax,[si]
	imul	[uz]
	sub	eax,ebx
	sbb	edx,ecx
	jns     EdgeA82
	neg	edx
	neg	eax
	jnc     EdgeA82
	dec	edx
EdgeA82:pop	ecx
	sub	eax,[gl]
	sbb	edx,[gh]
	mov	ebx,eax
	or	ebx,edx
	jz	EdgeA85
	test	edx,edx
	jns	EdgeA90

EdgeA85:lds	si,[L]
	add	si,cs:[di]
	add	di,2
	lds	si,[si]
	add	si,cs:[di]
	add	di,2
	add	si,[x]
	mov	eax,[si]
	imul	ecx
	mov	ebx,eax
	mov	ecx,edx
	lds	si,[L]
	add	si,cs:[di]
	add	di,2
	lds	si,[si]
	add	si,cs:[di]
	add	di,2
	add	si,[x]
	mov	eax,[si]
	imul	[uz]
	sub	eax,ebx
	sbb	edx,ecx
	jns     EdgeA87
	neg	edx
	neg	eax
	jnc     EdgeA87
	dec	edx
EdgeA87:sub	eax,[gl]
	sbb	edx,[gh]
	jnc	EdgeA90
	mov	ax,1
	test	ax,ax
	jmp	EdgeAE
EdgeA90:xor	eax,eax
EdgeAE:	ret
endp


EdgeLineAsm proc uses ds es fs gs si di,L:far ptr dword,BG:far ptr dword,LUX:far ptr dword,LUY:far ptr dword,sizex:word
local	x:word
	cld
	les	di,[L]
	lfs	si,[LUX]
	lgs	si,[LUY]
	sub	[sizex],2
	jna     EdgeL30
	xor	eax,eax
	stosd
	mov	[x],1
	mov	bx,4
EdgeL10:push	bx
	push	[BG]
	mov	si,word ptr[LUX]
	push	dword ptr fs:[si+bx]
	mov	si,word ptr [LUY]
	push	dword ptr gs:[si+bx]
	push	[x]
	call	EdgeAsm
	pop	bx
	jz      EdgeL20
	lds	si,[BG]
	lds	si,[si+4]
	mov     eax,[si+bx]
EdgeL20:stosd			; es:[di]:=bod
	add	bx,4
	inc	[x]
	dec	[sizex]
	jne	EdgeL10
	xor	eax,eax
	stosd
EdgeL30:ret
endp

; ====== Laplacian Gausianu ======

DiffHor2 proc uses ds esi es edi,L:far ptr dword,L1:far ptr dword,sizex:word
	mov	cx,[sizex]
	dec	cx
	lds	si,[L1]
	les	di,[L]
	mov	ebx,[si+4]
	mov	edx,[si]
DiffH22:mov	eax,ebx
	sub	eax,edx
	mov	ebx,edx
	sub	eax,ebx
	mov	edx,[si+4]
	add	eax,edx
	mov	es:[di],eax
	add	di,4
	add	si,4
	loop	DiffH22
	mov	eax,ebx
	add	eax,eax
	sub	eax,edx
	sub	eax,edx
	mov	es:[di],eax
DiffH2E:ret
endp

DiffVer2 proc uses ds esi es edi,L:far ptr dword,L1:far ptr dword,L2:far ptr dword,L3:far ptr dword,sizex:word
	mov	cx,[sizex]
	les	di,[L]
	lfs	bx,[L1]
	lds	si,[L2]
	lgs	dx,[L3]
DiffV21:mov	eax,[si]
	add	eax,eax
	neg	eax
	add	si,4
	add	eax,fs:[bx]
	add	bx,4
	xchg	dx,bx
	add	eax,gs:[bx]
	xchg	dx,bx
	add	dx,4
	mov	es:[di],eax
	add	di,4
	loop	DiffV21
DiffV2E:ret
endp

AddHor  proc  uses ds esi es edi,L:far ptr dword,L1:far ptr dword,sizex:word
	mov	cx,[sizex]
	lds	si,[L1]
	les	di,[L]
AddH2:  mov	eax,[si]
	add	eax,es:[di]
	mov	es:[di],eax
	add	si,4
	add	di,4
	loop	AddH2
AddHE:  ret
endp

	end